﻿using System;
using System.Collections.Generic;
using System.Linq;
using MVCms.Core.DataAccess;
using MVCms.Core.Entities;


namespace MVCms.Core.Services
{
    public static class PageService
    {

        /// <summary>
        /// Gets a list of all urls in the system
        /// </summary>
        /// <returns></returns>
        public static List<string> GetAllUrls()
        {
            List<string> _routes = new List<string>();

            //loop through all pages an get it's url
            try
            {
                foreach (var page in DataAccess.McContext.Load<VirtualPage>().ToList())
                {
                    // add the url to the routes
                    _routes.Add(GetPageUrl(page));
                }
            }
            catch 
            {
                

            }
            

            return _routes;
        }

        /// <summary>
        /// Gets the page's URL.
        /// </summary>
        /// <param name="page">The page.</param>
        /// <returns></returns>
        public static string GetPageUrl(VirtualPage page)
        {
            // add the current name
            string url = "/" + page.Name;

            // lop through parent's and insert their names infront of the url
            while (page.Parent != null)
            {
                url = string.Format("{0}{1}", "/" + page.Parent.Name, url);
                //sets the paget so it can continue the loop
                //if parent is null the loop exits and we have our url
                page = page.Parent;
            }

            return url;
        }

        /// <summary>
        /// Saves the specified page.
        /// </summary>
        /// <param name="page">The page.</param>
        /// <returns></returns>
        public static VirtualPage Save(this VirtualPage page)
        {
            DataAccess.McContext.Save(page);
            return page;
        }

        /// <summary>
        /// Gets all pages.
        /// </summary>
        /// <returns></returns>
        public static IList<VirtualPage> GetPages()
        {
            return DataAccess.McContext.Load<VirtualPage>().ToList();
        }

        /// <summary>
        /// Gets the page based on it's name.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <returns></returns>
        public static VirtualPage GetPage(string name)
        {
            return DataAccess.McContext.Load<VirtualPage>().Where(p => p.Name == name).FirstOrDefault();
        }

        /// <summary>
        /// Gets the page based on it's id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public static VirtualPage GetPage(int id)
        {
            return DataAccess.McContext.Load<VirtualPage>().Where(p => p.Id == id).FirstOrDefault();
        }

        /// <summary>
        /// Get's all the children of a page
        /// </summary>
        /// <param name="virtualPage">The virtual page.</param>
        /// <returns></returns>
        public static IEnumerable<VirtualPage> Children(this VirtualPage virtualPage)
        {
            return DataAccess.McContext.Load<VirtualPage>().Where(p => p.Parent == virtualPage).ToList();
        }

        /// <summary>
        /// Determines whether the specified virtual page has children.
        /// </summary>
        /// <param name="virtualPage">The virtual page.</param>
        /// <returns>
        /// 	<c>true</c> if the specified virtual page has children; otherwise, <c>false</c>.
        /// </returns>
        public static bool HasChildren(this VirtualPage virtualPage)
        {
            return DataAccess.McContext.Load<VirtualPage>().Where(p => p.Parent == virtualPage).Count() > 0;
        }

        /// <summary>
        /// Saves the specified page module.
        /// </summary>
        /// <param name="pageModule">The page module.</param>
        public static void Save(this PageModule pageModule)
        {
            McContext.Save(pageModule);
        }

        /// <summary>
        /// Updates the specified page module.
        /// </summary>
        /// <param name="pageModule">The page module.</param>
        public static void Update(this PageModule pageModule)
        {
            McContext.SaveChanges();
        }

        /// <summary>
        /// Gets the PageModule.
        /// </summary>
        /// <param name="module">The module.</param>
        /// <param name="page">The page.</param>
        /// <returns></returns>
        public static PageModule GetPageModule(PluginModule module, VirtualPage page)
        {
            return
                DataAccess.McContext.Load<PageModule>().Where(pm => pm.VirtualPage == page && pm.Module == module).
                    FirstOrDefault();
        }

        /// <summary>
        /// Check if the user can view this page
        /// </summary>
        /// <param name="page">The page.</param>
        /// <param name="userName">Name of the user.</param>
        /// <returns></returns>
        public static bool Allowed(this VirtualPage page, string userName)
        {
            if(page.PageRoles.Count == 0)
                return true;

            return page.PageRoles.Any(u => u.Users.Any(a => a.UserName == userName));
        }

        /// <summary>
        /// check if the user can view this module
        /// </summary>
        /// <param name="module">The module.</param>
        /// <param name="userName">Name of the user.</param>
        /// <returns></returns>
        public static bool Allowed(this PageModule module, string userName)
        {
            if (module.ModuleRoles.Count == 0)
                return true;

            return module.ModuleRoles.Any(u => u.Users.Any(a => a.UserName == userName));
        }
    }
}
